package com.nexgo.payment.trans.scanvoid;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.nexgo.payment.aop.annotation.TransCondition;
import com.nexgo.payment.trans.TransFlow;
import com.nexgo.data.entity.RecvData;
import com.nexgo.oaf.apiv3.emv.EmvChannelTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvProcessResultEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransDataEntity;
import com.nexgo.payment.App;
import com.nexgo.payment.R;
import com.nexgo.payment.action.ActionResult;
import com.nexgo.payment.action.ActionStep;
import com.nexgo.payment.constrant.CardMode;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.databases.TransRecord;
import com.nexgo.payment.entity.TransData;
import com.nexgo.payment.trans.AbsTransPresenter;
import com.nexgo.payment.util.TransUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 扫码撤销
 *
 * @author 谭忠扬-YuriTam
 * @time 2017年9月13日
 */
@TransCondition
@TransFlow
public class ScanVoidPresenter extends AbsTransPresenter implements ScanVoidContract.Presenter {
    private final Logger mLog = LoggerFactory.getLogger(ScanVoidPresenter.class.getSimpleName());

    private final ScanVoidContract.View mView;
    private String mTraceCode;
    private boolean mIsScanNext = false;

    public ScanVoidPresenter(@NonNull ScanVoidContract.View view, @NonNull DataSource repository, String traceCode) {
        super(view, repository);
        mView = checkNotNull(view);
        mTraceCode = traceCode;
        mView.setPresenter(this);
    }

    @Override
    protected TransData getTransData() {
        TransData transData = new TransData();
        transData.setTransType(TransType.SCAN_VOID);
        return transData;
    }

    @Override
    protected EmvTransDataEntity getEmvTransData(EmvChannelTypeEnum channelType) {
        return null;
    }

    @Override
    protected void onFirstAction() {
        postMainThread(() -> mView.showInputAdminPassword());
    }

    @Override
    public void importActionResult(ActionResult actionResult) {
        Object data = actionResult.getData();
        ActionStep step = (ActionStep) actionResult.getAction().getActionStep();
        int ret = actionResult.getRet();
        mLog.debug("curr action step {} ret {}", step, actionResult.getRet());
        //成功处理进行处理，否则让父类处理
        if (ret == ActionResult.SUCC) {
            switch (step) {
                case INPUT_ADMIN_PSW:
                    inputAdminPasswordNext(data);
                    break;
                case INPUT_TRACE_CODE:
                    inputTraceCodeNext(data);
                    break;
                case INPUT_SCAN:
                    inputScanNext(data);
                    return;
                case CONFIRM_TRANS_DETAIL:
                    confirmTransDetailNext(data);
                    break;
                default:
                    break;
            }
        }
        super.importActionResult(actionResult);
    }

    /**
     * 输入主管密码后下一步
     *
     * @param data
     */
    protected void inputAdminPasswordNext(Object data) {
        if (TextUtils.isEmpty(mTraceCode)){
            postMainThread(() -> mView.showInputTraceCode());
            return;
        }
        mTransData.setTraceCode(mTraceCode);
        confirmTransDetailNext(null);
    }

    /**
     * 输入凭证码后下一步
     *
     * @param data
     */
    protected void inputTraceCodeNext(Object data) {
        String traceCode = (String) data;
        if (TextUtils.isEmpty(traceCode)) {
            //跳去扫码
            postMainThread(() -> mView.showScanFragment());
            return;
        }
        //凭证码输入完毕，进入输退款金额
        mTransData.setTraceCode(traceCode);
        judgeTraceCode(mTransData.getTraceCode());
    }

    /**
     * 扫码后下一步动作
     *
     * @param data
     */
    protected void inputScanNext(Object data) {
        mTransData.setTraceCode((String) data);
        //不从此处发起输入金额，需要等待此Activity状态恢复之后才能发起，不然会报异常
        mIsScanNext = true; //记录扫码后的状态
    }

    @Override
    public void showOnScanNextAndRestart() {
        if (!mIsScanNext) return;
        judgeTraceCode(mTransData.getTraceCode());
        mIsScanNext = false;
    }

    /**
     * 判断输入的凭证码是否存在相应的交易记录
     */
    protected void judgeTraceCode(String traceCode) {
        TransRecord transRecord = mRepository.queryScanTransRecord(traceCode);
        if (transRecord == null) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.this_pay_trace_code_no_exist)));
            return;
        }
        if (TransType.SCAN_SALE.ordinal() != transRecord.getTransType() ||TransType.SCAN_ORDER.ordinal() != transRecord.getTransType() || !transRecord.getIsSuccess()) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.err_trans_type_for_void)));
            return;
        }
        if (transRecord.getIsVoid()) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.err_trans_is_void)));
            return;
        }
        postMainThread(() -> mView.showConfirmTransDetail(mTransData.getTraceCode()));
    }

    /**
     * 确认交易信息下一步
     *
     * @param data
     */
    protected void confirmTransDetailNext(Object data) {
        TransRecord transRecord = null;
        if (!TextUtils.isEmpty(mTraceCode)){
            transRecord = mRepository.queryScanTransRecord(mTraceCode);
        }else {
            transRecord = (TransRecord) data;
        }
        //不参与后继的组包 ，记录更新撤销标识及保存到数据库
        mTransData.setPayCodeNo(transRecord.getPayCodeNo());
        mTransData.setOrgTraceNum(transRecord.getTraceNum());
        mTransData.setCardMode(CardMode.SCAN);
        mTransData.setEntryMode(TransUtils.getEntryMode(mTransData.getCardMode(), null, mTransData.getPin() != null , mTransData.isFallback()));
        postMainThread(() -> mView.showOnlineProc(mTransData, null));
    }

    @Override
    protected void onTransSuccess(RecvData recvData, EmvProcessResultEntity emvResult) {
        mView.quitTrans();
    }

}
